﻿using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace EasyNet.Componets.Core.Algorithms
{
    public sealed class DES
    {
        private static DES _instance;
        /// <summary>
        /// 单一实例
        /// </summary>
        public static DES Instance
        {
            get
            {

                return _instance = _instance ?? new DES();
            }
        }
        
        #region DES加密
        /// <summary>
        ///     进行DES加密。
        /// </summary>
        /// <param name="encryptString">要加密的字符串。</param>
        /// <param name="sKey">密钥，且必须为8位。</param>
        /// <param name="sIV">密钥，且必须为8位。</param>
        /// <returns>以Base64返回的加密字符串。</returns>
        public string Encrypt2Base64(string encryptString, string sKey, string sIV, Encoding encoding = null)
        {
            var buffer = Encrypt2Bytes(encryptString, sKey, sIV, encoding);

            return Convert.ToBase64String(buffer);
        }

        /// <summary>
        ///     进行DES加密。
        /// </summary>
        /// <param name="encryptString">要加密的字符串。</param>
        /// <param name="sKey">密钥，且必须为8位。</param>
        /// <param name="sIV">密钥，且必须为8位。</param>
        /// <returns>以byte[]返回的加密字符串。</returns>
        public byte[] Encrypt2Bytes(string encryptString, string sKey, string sIV, Encoding encoding = null)
        {
            if (sKey.Length != 8 || sIV.Length != 8) throw new ApplicationException();
            encoding = encoding ?? Encoding.UTF8;
            using (var des = new DESCryptoServiceProvider
            {
                Key = encoding.GetBytes(sKey),
                IV = encoding.GetBytes(sIV)
            })
            using (var ms = new MemoryStream())
            using (var cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write))
            {
                byte[] buffer = encoding.GetBytes(encryptString);
                cs.Write(buffer, 0, buffer.Length);
                cs.FlushFinalBlock();

                return ms.ToArray();
            }
        }
        #endregion

        #region DES解密
        /// <summary>
        ///     进行DES解密。
        /// </summary>
        /// <param name="decryptBase64">要解密的以Base64</param>
        /// <param name="sKey">密钥，且必须为8位。</param>
        /// <param name="sIV">密钥，且必须为8位。</param>
        /// <returns>已解密的字符串。</returns>
        public string DecryptByBase64(string decryptBase64, string sKey, string sIV, Encoding encoding = null)
        {
            encoding = encoding ?? Encoding.UTF8;
            var decryptBuffer = Convert.FromBase64String(decryptBase64);

            return DecryptByBytes(decryptBuffer, sKey, sIV, encoding);
        }
        /// <summary>
        ///     进行DES解密。
        /// </summary>
        /// <param name="decryptBuffer">要解密的以byte[]/param>
        /// <param name="sKey">密钥，且必须为8位。</param>
        /// <param name="sIV">密钥，且必须为8位。</param>
        /// <returns>已解密的字符串。</returns>
        public string DecryptByBytes(byte[] decryptBuffer, string sKey, string sIV, Encoding encoding = null)
        {
            if (sKey.Length != 8 || sIV.Length != 8) throw new ApplicationException();
            encoding = encoding ?? Encoding.UTF8;
            using (var des = new DESCryptoServiceProvider
            {
                Key = encoding.GetBytes(sKey),
                IV = encoding.GetBytes(sIV)
            })
            using (var ms = new MemoryStream(decryptBuffer))
            using (var cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Read))
            using (var sr = new StreamReader(cs, encoding))
            {
                return sr.ReadToEnd();
            }
        }
        #endregion

    }
}
